package concurrent;

/**
 * @description: TODO 被synchronized修饰的代码块或方法，只有多个线程针对同一个对象才有效。
 * @author: wzj
 * @create: 2019/1/26 13:57
 */
public class SynchronizedDemo {
    //修饰实例方法
    //针对同一个SynchronizedDemo实例 线程从这里开始阻塞
    public synchronized void method1(String str){
        System.out.println("之前："+str);
        try {
            System.out.println(str);
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("之后："+str);
    }

    //代码块this
    public void method2(String str){
        System.out.println("synchronized块之前："+str);
        try {
            //线程从这里开始阻塞
            synchronized (this) {//this是当前对象实例，SynchronizedDemo.class是类对象，不一样
                System.out.println(str);
                Thread.sleep(5000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("synchronized块之后："+str);
    }
    private String syncstr="";
    //代码块效果同this
    public void method20(String str){
        System.out.println("synchronized块之前method20："+str);
        try {
            //针对同一个SynchronizedDemo实例的成员变量 到这里阻塞
            synchronized (syncstr) {//相同效果：这个需要syncstr有值 不为null
                System.out.println("method20"+str);
                Thread.sleep(5000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("synchronized块之后method20："+str);
    }

    //针对局部变量synchronized没什么作用
    public void method30(String str){
        Object obj=new Object();
        System.out.println("synchronized块之前method30："+str);
        try {
            synchronized (obj) {//针对局部变量 没啥作用
                System.out.println("method30"+str);
                Thread.sleep(5000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("synchronized块之后method30："+str);
    }

    //代码块 所有线程针对同一个对象才起作用
    public void method4(Object obj,String str){
        System.out.println("synchronized块之前："+str);
        try {
            //线程从这里开始阻塞
            synchronized (obj) {
                System.out.println(str);
                Thread.sleep(5000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("synchronized块之后："+str);
    }

    public static void main(String[] args) {
        SynchronizedDemo s=new SynchronizedDemo();
        T t=new T();
        for(int i=0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    s.method4(t,Thread.currentThread().getName());
                }
            }).start();
        }
    }

}
class T{}